/*
 * ========================================
 * RISC-V 架构相关定义
 * ========================================
 * 这个文件定义了RISC-V架构相关的常量、寄存器和数据结构
 * 主要用于内存管理、页表操作和特权级控制
 */

#ifndef RISCV_H
#define RISCV_H

#include "types.h"

// ========================================
// RISC-V 特权级定义
// ========================================
#define MACHINE_MODE    3    // 机器模式（最高特权级）
#define SUPERVISOR_MODE 1    // 监管者模式
#define USER_MODE       0    // 用户模式（最低特权级）

// ========================================
// 页表相关定义
// ========================================
#define PGSIZE          4096        // 页大小：4KB
#define PGSHIFT         12          // 页大小位移：2^12 = 4096
#define PGMASK          (PGSIZE-1)  // 页掩码：0xFFF

// 页表项（PTE）相关定义
#define PTE_V           (1L << 0)   // 有效位：页表项是否有效
#define PTE_R           (1L << 1)   // 读权限：是否可读
#define PTE_W           (1L << 2)   // 写权限：是否可写
#define PTE_X           (1L << 3)   // 执行权限：是否可执行
#define PTE_U           (1L << 4)   // 用户权限：用户模式是否可访问
#define PTE_G           (1L << 5)   // 全局页：所有地址空间共享
#define PTE_A           (1L << 6)   // 访问位：页是否被访问过
#define PTE_D           (1L << 7)   // 脏位：页是否被修改过

// 页表项掩码
#define PTE_PPN_SHIFT   10          // 物理页号位移
#define PTE_PPN_MASK    (0x3FFFFFFFFFFFULL << PTE_PPN_SHIFT)

// ========================================
// 虚拟地址和物理地址定义
// ========================================
#define VA_BITS         39          // 虚拟地址位数（Sv39）
#define PA_BITS         56          // 物理地址位数
#define VA_MASK         ((1ULL << VA_BITS) - 1)
#define PA_MASK         ((1ULL << PA_BITS) - 1)

// 地址空间布局（注释掉，避免与memlayout.h重复定义）
// #define KERNBASE        0x80000000L // 内核基地址
// #define PHYSTOP         (KERNBASE + 128*1024*1024) // 物理内存结束地址

// ========================================
// 页表结构定义
// ========================================
// 页表项类型
typedef uint64 pte_t;

// 页表类型
typedef pte_t* pagetable_t;

// ========================================
// 内存管理相关定义
// ========================================
#define MAXVA           (1L << (VA_BITS - 1))  // 最大虚拟地址
#define PGROUNDUP(sz)   (((sz)+PGSIZE-1) & ~PGMASK)  // 向上对齐到页边界
#define PGROUNDDOWN(a)  (((a)) & ~PGMASK)      // 向下对齐到页边界

// ========================================
// 寄存器相关定义
// ========================================
// SATP寄存器相关
#define SATP_MODE_SV39  (8L << 60)  // Sv39模式
#define SATP_ASID_SHIFT 44          // ASID位移
#define SATP_PPN_SHIFT  0           // 页表根页号位移

// ========================================
// 内存屏障指令
// ========================================
#define sfence_vma()    asm volatile("sfence.vma zero, zero" : : : "memory")

// ========================================
// 页表操作宏
// ========================================
// 从页表项中提取物理页号
#define PTE2PA(pte)     (((pte) >> PTE_PPN_SHIFT) << PGSHIFT)

// 从物理地址生成页表项
#define PA2PTE(pa)      ((((uint64)pa) >> PGSHIFT) << PTE_PPN_SHIFT)

// 检查页表项是否有效
#define PTE_VALID(pte)  ((pte) & PTE_V)

// 检查页表项是否有读权限
#define PTE_READABLE(pte) ((pte) & PTE_R)

// 检查页表项是否有写权限
#define PTE_WRITABLE(pte) ((pte) & PTE_W)

// 检查页表项是否有执行权限
#define PTE_EXECUTABLE(pte) ((pte) & PTE_X)

// ========================================
// 地址转换相关
// ========================================
// 从虚拟地址提取页号
#define VPN0(va)        (((va) >> 12) & 0x1FF)  // 第0级页号
#define VPN1(va)        (((va) >> 21) & 0x1FF)  // 第1级页号
#define VPN2(va)        (((va) >> 30) & 0x1FF)  // 第2级页号

// 从虚拟地址提取页内偏移
#define PGOFF(va)       ((va) & PGMASK)

// ========================================
// 内存分配相关
// ========================================
#define NCPU            8           // 最大CPU核心数
#define KSTACKSIZE      4096        // 内核栈大小

// ========================================
// 调试相关
// ========================================
#define DEBUG_MEM       1           // 内存管理调试开关
#define DEBUG_PAGE      1           // 页表调试开关

#endif // RISCV_H
